package com.gitee.urick.union.api.union.dto;

import com.alibaba.fastjson.JSON;
import com.gitee.urick.union.api.union.dto.base.BaseReq;
import com.gitee.urick.union.api.union.dto.base.BaseRes;
import com.gitee.urick.union.utils.TipsCode;
import lombok.Getter;

import java.util.HashMap;
import java.util.Map;

/**
 * 修改记录
 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 * 修改日期				修改者						备注信息
 * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 * 2020年08月20日			kkroc							初始化版本
 */

public class ReqCtx {
    private static final String KEY_REQ = "key.api.req";
    private static final String KEY_RES = "key.api.res";
    @Getter
    private final String action;
    @Getter
    private final String reqJson;
    @Getter
    private final String sign;
    private final Map<String, Object> map;
    private boolean terminated = false;
    private boolean handled = false;


    public static ReqCtx newCtx(String action, String data, String sign) {
        return new ReqCtx(action, data, sign);
    }

    private ReqCtx(String action, String reqJson, String sign) {
        this.action = action;
        this.reqJson = reqJson;
        this.sign = sign;
        this.map = new HashMap<>();
    }

    public <T> T getReq(Class<T> clazz) {
        T req = (T) map.get(clazz.getSimpleName());
        if (req == null) {
            req = JSON.parseObject(reqJson, clazz);
            map.put(clazz.getSimpleName(), req);
        }
        return req;
    }

    public <T> T getAttribute(String key) {
        return (T) map.get(key);
    }

    public void setAttribute(String key, Object value) {
        map.putIfAbsent(key, value);
    }

    public <Q extends BaseReq> void setReq(Q req) {
        if (req == null) return;
        map.putIfAbsent(KEY_REQ, req);
    }

    public <Q extends BaseReq> Q getReq() {
        return (Q) map.get(KEY_REQ);
    }

    public <R extends BaseRes> void setRes(R res) {
        if (res == null) return;
        map.putIfAbsent(KEY_RES, res);
    }

    public <R extends BaseRes> R getRes() {
        return (R) map.get(KEY_RES);
    }

    public void terminate() {
        terminated = true;
    }

    public void handled() {
        handled = true;
    }

    public boolean isTerminated() {
        return terminated;
    }

    public boolean isHandled() {
        return handled;
    }

    ;

    public void makeTips(TipsCode code, Object... args) {
        switch (code.getLevel()) {
            case Error:
                if (!isTerminated()) terminate();
                break;
            case Handled:
            case Info:
                if (!isTerminated()) handled();
                break;
        }
        BaseRes res = getRes();
        if (res == null) {
            res = new BaseRes();
            setRes(res);
        }
        String message = String.format(code.getPattern(), args);
        if (isTerminated())
            res.error(message);
        else
            res.success(message);
    }
}
